﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

using ArcannEngine.Scene;
using ArcannEngine.Components;
using ArcannEngine.Render;

namespace ArcannEngine.Entities
{
    public class RocketEntity : Entity
    {
        //przyspieszenie
        public float acceleration;
        public float newAcceleration;

        //masa
        float m_corps = 0; //masa korpusu
        public float m_total = 0; //masa laczna

        public float v_rocket = 0; //predkosc rakiety

        public float area = 0; //pole powierzchni kadluba

        //sily
        public float f_t = 0; //sila ciagu
        public float f_g = 0; //sila ciezkosci
        public float f_d = 0; //sila oporu aero
        float f_y = 0;

        //calkowanie
        float dy = 0;
        float dt = 0.02f;

        //wysokosc
        public float height = 0;
        public float startFloat = 0;

        //dzialajaca aktualnie czesc rakiety
        public int working_part = 0;

        //elementy skladowe rakiety
        public Element top = null;
        public Element middle = null;
        public Element bottom = null;

        //CZAS
        double timer = 0;
        public int time = 0;
        int oldTime = 0;
        int timer2 = 0;
        double oldTimer = 0;

        //DANE DOMYSLNE
        RocketEntity defaultRocket;

        Entity camera;

        public RocketEntity(SceneManager scene, string name, float m_corps, float m_fuel, Entity camera)
            : base(scene, name)
        {
            this.m_corps = m_corps;
            this.m_total = m_corps + m_fuel;
            this.camera = camera;

            Init(m_fuel);
        }
        private void Init(float m_fuel)
        {
            //OPISZE ZEBY BYLO CI LATWIEJ
            this.position = new Vector3(-700, 0, 500); //oczywiste
            this.rotation = Matrix.CreateRotationY(MathHelper.ToRadians(270f));//zeby nie stal tylem
            RenderComponent rendComp = new RenderComponent(this, "Models/rocket");//dodajemy komponent rysowania, w konstruktorze obiekt, do ktorego jest przypisany i model graf.
            TerrainCollisionComponent terrainCollisionComp = new TerrainCollisionComponent(this, 256f); //komponent kolizji z terenem

            //TOP SECTION
            top = new Element(this, 9560, 1100f);
            //engines - J2 x 1 ~ 1033kN
            top.addEngine(Engine.EngineType.REGULAR, 1033f);

            //MIDDLE SECTION
            middle = new Element(this, 25000, 100000);

            //engines J2 x 5 ~ 5150 kN
            middle.addEngine(Engine.EngineType.REGULAR, 1033f);
            middle.addEngine(Engine.EngineType.REGULAR, 1033f);
            middle.addEngine(Engine.EngineType.REGULAR, 1033f);
            middle.addEngine(Engine.EngineType.REGULAR, 1033f);
            middle.addEngine(Engine.EngineType.REGULAR, 1033f);

            //BOTTOM SECTION
            bottom = new Element(this, 0, 100000);
            //engines F1 x 5 ~ 34 kN
            bottom.addEngine(Engine.EngineType.STARTER, 4200f);
            bottom.addEngine(Engine.EngineType.STARTER, 4200f);
            bottom.addEngine(Engine.EngineType.STARTER, 4200f);
            bottom.addEngine(Engine.EngineType.STARTER, 4200f);
            bottom.addEngine(Engine.EngineType.STARTER, 4200f);

            area = (float)(Math.PI * 2 * 2);

            m_total = bottom.getWeight() + middle.getWeight() + top.getWeight();

            defaultRocket = (RocketEntity)MemberwiseClone(); //konfiguracja startowa
        }

        public override void Update(GameTime gameTime)
        {
            base.Update(gameTime);
            if (this.height > 28000)
            {
                //World.stopped = true;
            }

            float moved = 0;
            if (timer == 0)
            {
                startFloat = this.position.Y;
            }
            if (World.resetSignal == true)
            {
                Reset();
                World.resetSignal = false;
            }

            int div;
            timer2++;
            if (World.slowMo == true)
            {
                div = 5;
            }
            else
            {
                div = 1;
            }

            if (timer2 == int.MaxValue)
            {
                timer2 = 0;
            }

            if (World.stopped != true)
            {
                if (timer2 % div == 0)
                {
                    timer += gameTime.ElapsedGameTime.TotalSeconds;

                    time = (int)timer; //CZAS, KTORY UPLYNAL
                    //Console.WriteLine("Czas: " + (timer - oldTimer));
                    //Console.WriteLine("Czas stary: " + oldTimer);
                    if (time != oldTime)
                    {
                        m_total = bottom.getWeight() + middle.getWeight() + top.getWeight();

                        //Console.WriteLine(m_total);

                        f_g = m_total * World.g;//grawitacja
                        f_d = v_rocket / 10 * v_rocket / 10 * area * World.cd * World.rho; //opór powietrza

                        //Console.WriteLine(f_g + ", " + f_d);

                        f_t = 0;

                        if (top.fuelContainer + bottom.fuelContainer + middle.fuelContainer > 0)
                        {
                            if (bottom.disconnected == false)
                            {
                                f_t += bottom.calculateForce(time);
                                working_part = 1;
                            }
                            else if (middle.disconnected == false)
                            {
                                f_t += middle.calculateForce(time);
                                working_part = 2;
                            }
                            else if (top.disconnected == false)
                            {
                                f_t += top.calculateForce(time);
                                working_part = 3;
                            }
                        }
                        //VERLET VELOCITY INTEGRATION
                        dt = (float)(timer - oldTimer);
                        dy = v_rocket * dt + (0.5f * acceleration * dt * dt);

                        f_y = (f_t - (f_g + f_d));

                        newAcceleration = f_y / m_total;
                        acceleration = (newAcceleration + acceleration) * 0.5f;

                        v_rocket += acceleration / 10;

                    }
                    moved = (this.GetComponent("TerrainCollision") as TerrainCollisionComponent).baseOffset + v_rocket * time;
                    if ((position.Y + v_rocket <= Manager.HeightMapInfo.GetHeight(position) + (this.GetComponent("TerrainCollision") as TerrainCollisionComponent).baseOffset))
                    {
                        dy = 0;
                        v_rocket = 0;
                    }
                    (this.GetComponent("TerrainCollision") as TerrainCollisionComponent).floatOffset += dy * 10f; //tutaj tak zeby cos sie dzialo
                    oldTimer = timer;

                }
            }

            height = this.position.Y - startFloat;
            height *= 0.1f;

            oldTime = time;

        }

        public void Reset()
        {
            this.position = defaultRocket.position;
            (this.GetComponent("TerrainCollision") as TerrainCollisionComponent).floatOffset = (this.GetComponent("TerrainCollision") as TerrainCollisionComponent).baseOffset;
            this.acceleration = defaultRocket.acceleration;
            this.newAcceleration = defaultRocket.newAcceleration;

            this.m_corps = defaultRocket.m_corps;
            this.m_total = defaultRocket.m_total;
            this.v_rocket = defaultRocket.v_rocket;
            this.area = defaultRocket.area;
            this.f_t = defaultRocket.f_t;
            this.f_g = defaultRocket.f_g;
            this.f_d = defaultRocket.f_d;

            this.top = defaultRocket.top;
            this.middle = defaultRocket.middle;
            this.bottom = defaultRocket.bottom;

            this.top.fuelContainer = 1100;
            this.middle.fuelContainer = 100000;
            this.bottom.fuelContainer = 100000;

            this.dy = defaultRocket.dy;
            this.dt = defaultRocket.dt;


            this.timer2 = 0;
            this.timer = 0;
            this.oldTime = defaultRocket.oldTime;
            this.time = defaultRocket.time;

            World.stopped = true;
        }
    }
}
